home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE20 / CLINIC / Directio / POKEIO.C next >
Encoding:
C/C++ Source or Header  |  1996-04-03  |  2.4 KB  |  85 lines

  1. /*********************************************************************
  2.  
  3.   This code fragment illustrates the unsuccessful attempt to directly
  4. modify the IOPM base address.  This code would appear in a kernel
  5. mode device driver.  Refer to the GIVEIO.C listing for a complete
  6. device driver example.
  7.  
  8. *********************************************************************/
  9.  
  10. /*
  11.  *  Make sure our structure is packed properly, on byte boundary, not
  12.  * on the default doubleword boundary.
  13.  */
  14. #pragma pack(push,1)
  15.  
  16. /*
  17.  *  Structure of a GDT (global descriptor table) entry.  From
  18.  * processor manual.
  19.  */
  20. typedef struct {
  21.     unsigned limit : 16;
  22.     unsigned baselo : 16;
  23.     unsigned basemid : 8;
  24.     unsigned type : 4;
  25.     unsigned system : 1;
  26.     unsigned dpl : 2;
  27.     unsigned present : 1;
  28.     unsigned limithi : 4;
  29.     unsigned available : 1;
  30.     unsigned zero : 1;
  31.     unsigned size : 1;
  32.     unsigned granularity : 1;
  33.     unsigned basehi : 8;
  34. } GDTENT;
  35.  
  36. /*
  37.  *  Structure of the 48 bits of the GDT register that are stored
  38.  * by the SGDT instruction.
  39.  */
  40. typedef struct {
  41.     unsigned short  limit;
  42.     GDTENT  *base;
  43. } GDTREG;
  44.  
  45. #pragma pack(pop)
  46.  
  47. /*
  48.  *  This code demonstrates the brute force approach to modifying
  49.  * the IOPM base.  The IOPM base is stored as a two byte integer
  50.  * at offset 0x66 within the TSS, as documented in the processor
  51.  * manual.  In Windows NT, the IOPM is stored within the TSS
  52.  * starting at offset 0x88, and going for 0x2004 bytes.  This is
  53.  * not documented anywhere, and was determined by inspection.
  54.  * The code here puts some 0's into the IOPM so that we
  55.  * can try to access some I/O ports, then modifies the IOPM base
  56.  * address.
  57.  *
  58.  *  This code is unsuccessful because NT overwrites the IOPM
  59.  * base on each process switch.
  60.  */
  61. void GiveIO()
  62. {
  63.     GDTREG gdtreg;
  64.     GDTENT *g;
  65.     short TaskSeg;
  66.     char *TSSbase;
  67.     int i;
  68.  
  69.     _asm str TaskSeg;                                       // get the TSS selector
  70.     _asm sgdt gdtreg;                                       // get the GDT address
  71.  
  72.     g = gdtreg.base + (TaskSeg >> 3);       // get the TSS descriptor
  73.  
  74.                                         // get the TSS address
  75.     TSSbase = (PVOID)(g->baselo | (g->basemid << 16) 
  76.                | (g->basehi << 24));
  77.  
  78.     for(i=0; i < 16; ++i)                           // poke some 0's into the
  79.         TSSbase[0x88 + i] = 0;                  //   IOPM
  80.  
  81.                                         // set IOPM base to 0x88
  82.     *((USHORT *)(TSSbase + 0x66)) = 0x88;
  83. }
  84.  
  85.